﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace Monocle.ViewHelpers
{
    public class ExtensionsFactory
    {
        private HtmlHelper _htmlHelper;

        public ExtensionsFactory(HtmlHelper htmlHelper)
        {
            if (htmlHelper == null)
                throw new ArgumentNullException("htmlHelper");

            _htmlHelper = htmlHelper;

        }

        /// <summary>
        /// Creates a toolbar button control as a form with an image submit button
        /// </summary>
        /// <param name="actionName">The name of the action to perfom</param>
        /// <param name="imageUrl">The URL of the image for the button</param>
        /// <param name="toolTip">Text used in tooltip</param>
        /// <param name="routeValues"></param>
        /// <param name="formHtmlAttributes">A set of attribute key/value pairs for the form</param>
        /// <param name="inputHiddenHtmlAttributes">A set of attribute key/value pairs for the ID field (hidden)</param>
        /// <param name="inputImageHtmlAttributes">A set of attribute key/value pairs for the image button</param>
        /// <returns>Html to render the control</returns>
        public HtmlString ToolBarFormButton(string actionName, string controllerName, string imageUrl, string toolTip, object routeValues, object formHtmlAttributes, object inputHiddenHtmlAttributes, object inputImageHtmlAttributes)
        {

            var urlHelper = new UrlHelper(_htmlHelper.ViewContext.RequestContext);
            var action = urlHelper.Action(actionName, controllerName, routeValues);

            // Create form
            var formTagBuilder = new TagBuilder("form");
            formTagBuilder.MergeAttribute("action", action);
            formTagBuilder.MergeAttribute("method", "get");
            formTagBuilder.MergeAttribute("style", "display:inline;");
            //formTagBuilder.MergeAttribute("class", "ToolBarButton");
            formTagBuilder.MergeAttributes(new RouteValueDictionary(formHtmlAttributes));

            //Create hidden input, which holds ID of the selected row
            var inputHiddenTagBuilder = new TagBuilder("input");
            inputHiddenTagBuilder.MergeAttribute("type", "hidden");
            inputHiddenTagBuilder.MergeAttribute("name", "id");
            inputHiddenTagBuilder.MergeAttribute("value", "");
            inputHiddenTagBuilder.MergeAttributes(new RouteValueDictionary(inputHiddenHtmlAttributes));

            //Create input image (button)
            var inputImageTagBuilder = new TagBuilder("input");
            inputImageTagBuilder.MergeAttribute("type", "image");
            inputImageTagBuilder.MergeAttribute("src", urlHelper.Content(imageUrl));
            inputImageTagBuilder.MergeAttribute("class", "ToolBarButtonImage ToolBarButton");
            inputImageTagBuilder.MergeAttribute("title", toolTip);
            inputImageTagBuilder.MergeAttributes(new RouteValueDictionary(inputImageHtmlAttributes));

            // Add hidden input and image input to form
            formTagBuilder.InnerHtml = inputHiddenTagBuilder.ToString(TagRenderMode.SelfClosing) + inputImageTagBuilder.ToString(TagRenderMode.SelfClosing);

            var result = new HtmlString(formTagBuilder.ToString(TagRenderMode.Normal));

            return result;
        }

        public HtmlString ImageLinkButton(string actionName, string controllerName, string imageUrl, string toolTip, object routeValues, object inputImageHtmlAttributes)
        {
            var urlHelper = new UrlHelper(_htmlHelper.ViewContext.RequestContext);
            var action = urlHelper.Action(actionName, controllerName, routeValues);

            //Create input image (button)
            var inputImageTagBuilder = new TagBuilder("img");
            inputImageTagBuilder.MergeAttribute("src", urlHelper.Content(imageUrl));
            inputImageTagBuilder.MergeAttribute("class", "ImageLinkButton");
            inputImageTagBuilder.MergeAttribute("alt", toolTip);
            inputImageTagBuilder.MergeAttributes(new RouteValueDictionary(inputImageHtmlAttributes));

            var linkTagBuilder = new TagBuilder("a");
            linkTagBuilder.MergeAttribute("href", action);
            linkTagBuilder.MergeAttribute("class", "");
            linkTagBuilder.InnerHtml = inputImageTagBuilder.ToString();

            var result = new HtmlString(linkTagBuilder.ToString());

            return result;
        }

        public HtmlString ImageLinkButtonWithText(string actionName, string controllerName, string imageUrl, string toolTip, string buttonText, object routeValues, object linkHtmlAttributes, object imageHtmlAttributes)
        {

            var urlHelper = new UrlHelper(_htmlHelper.ViewContext.RequestContext);
            var url = "#";
            if (!String.IsNullOrEmpty(actionName))
                url = urlHelper.Action(actionName, controllerName, routeValues);

            // Create link
            var linkTagBuilder = new TagBuilder("a");
            linkTagBuilder.MergeAttribute("href", url);
            linkTagBuilder.MergeAttribute("class", "");
            linkTagBuilder.MergeAttribute("title", toolTip);
            linkTagBuilder.MergeAttributes(new RouteValueDictionary(linkHtmlAttributes));

            // Create image
            var imageTagBuilder = new TagBuilder("img");
            imageTagBuilder.MergeAttribute("src", urlHelper.Content(imageUrl));
            imageTagBuilder.MergeAttribute("alt", toolTip);
            imageTagBuilder.MergeAttribute("class", "ImageLinkButton");
            imageTagBuilder.MergeAttributes(new RouteValueDictionary(imageHtmlAttributes));

            // Add image to link
            linkTagBuilder.InnerHtml = imageTagBuilder.ToString(TagRenderMode.SelfClosing) + buttonText;

            var result = new HtmlString(linkTagBuilder.ToString(TagRenderMode.Normal));

            return result;
        }

        public IHtmlString SaveButton()
        {
            var inputTagBuilder = new TagBuilder("button");
            inputTagBuilder.MergeAttribute("type", "hidden");
            inputTagBuilder.InnerHtml = Monocle.Resources.Monocle.Generic_Save;
            return _htmlHelper.Raw(inputTagBuilder.ToString());
        }

        public IHtmlString CancelLink(String action, String controller, object routeValues)
        {
            var urlHelper = new UrlHelper(_htmlHelper.ViewContext.RequestContext);
            var url = routeValues == null ? urlHelper.Action(action, controller) : urlHelper.Action(action, controller, routeValues);

            var containerTagBuilder = new TagBuilder("div");
            containerTagBuilder.MergeAttribute("class", "LinkContainer");
            containerTagBuilder.MergeAttribute("title", "Annuller");

            var linkTagBuilder = new TagBuilder("a");
            linkTagBuilder.MergeAttribute("href", url);
            linkTagBuilder.MergeAttribute("class", "CancelLink");
            linkTagBuilder.InnerHtml = Monocle.Resources.Monocle.Generic_Cancel;

            return _htmlHelper.Raw(linkTagBuilder.ToString(TagRenderMode.Normal));
        }

        public IHtmlString BasicCancelLink(String action, String controller)
        {
            return CancelLink(action, controller, null);
        }

        #region breadcrumb
        /// <summary>
        /// Creates a breadcrumb text
        /// </summary>
        /// <param name="breadCrumbValues">A string representing the breadcrumb path delimited by semicolons</param>
        /// <returns>Html to render the control</returns>
        public HtmlString BreadCrumb(string breadCrumbValues)
        {
            string[] breadCrumbItems = breadCrumbValues.Split(';');

            var breadCrumbDelimiter = "|";

            // Create break
            var breakTagBuilder = new TagBuilder("br");

            // Create breadcrumb container
            var containerTagBuilder = new TagBuilder("div");
            containerTagBuilder.MergeAttribute("class", "breadcrumbContainer");

            // Create breadcrumb delimiter
            var delimiterTagBuilder = new TagBuilder("div");
            delimiterTagBuilder.MergeAttribute("class", "breadcrumbDelimiter");
            delimiterTagBuilder.InnerHtml = breadCrumbDelimiter;

            for (int i = 0; i < breadCrumbItems.Length; i++)
            {
                // Create breadcrumb part
                var itemTagBuilder = new TagBuilder("div");
                itemTagBuilder.MergeAttribute("class", "breadcrumbItem");
                itemTagBuilder.InnerHtml = breadCrumbItems[i];
                if (!String.IsNullOrEmpty(containerTagBuilder.InnerHtml))
                {
                    // Add delimiter
                    containerTagBuilder.InnerHtml += delimiterTagBuilder.ToString(TagRenderMode.Normal);
                }
                // Add part to breadcrumb
                containerTagBuilder.InnerHtml += itemTagBuilder.ToString(TagRenderMode.Normal);
            }

            var result = new HtmlString(containerTagBuilder.ToString(TagRenderMode.Normal) + breakTagBuilder.ToString(TagRenderMode.SelfClosing));

            return result;
        }

        #endregion
    }

    public static class ExtensionsFactoryStatic
    {
        public static ExtensionsFactory Monocle(this HtmlHelper htmlHelper)
        {
            return new ExtensionsFactory(htmlHelper);
        }
    }
}